package com.wjh.utils;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.wjh.config.AlipayConfig;
import com.wjh.enums.AliPayPcWebRespCodeEnums;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;

/**
 * 对支付宝的接口进行封装
 * 
 * @author wenjianhai
 * @date 2023/6/28
 * @since JDK 17
 */
@Slf4j
@Component
public class AliPayHelper {

	@Resource
	private AlipayConfig alipayConfig;

	// 返回数据格式
	private static final String FORMAT = "json";
	// 编码类型
	private static final String CHART_TYPE = "GBK";
	// 签名类型
	private static final String SIGN_TYPE = "RSA2";

	/* 支付销售产品码,目前支付宝只支持FAST_INSTANT_TRADE_PAY */
	public static final String PRODUCT_CODE = "FAST_INSTANT_TRADE_PAY";

	private static AlipayClient alipayClient = null;

	@PostConstruct
	public void init() {
		alipayClient = new DefaultAlipayClient(alipayConfig.getGateway(), alipayConfig.getAppid(),
				alipayConfig.getPrivatekey(), FORMAT, CHART_TYPE, alipayConfig.getPublickey(), SIGN_TYPE);
	};

	/* ================PC网页支付==================== */
	/**
	 * 统一下单并调用支付页面接口
	 * 
	 * @param outTradeNo
	 * @param totalAmount 订单总金额。单位为元，精确到小数点后两位
	 * @param subject
	 * @return
	 */
	public Map<String, Object> placeOrderAndPayForPCWeb(String outTradeNo, BigDecimal totalAmount, String subject) {
		/* https://opendocs.alipay.com/open/59da99d0_alipay.trade.page.pay?pathHash=8e24911d */
		AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
		// 跳转接口地址
		request.setNotifyUrl(alipayConfig.getNotifyurl());
		// 跳转页面地址
		request.setReturnUrl(alipayConfig.getReturnurl());
		JSONObject bizContent = new JSONObject();
		bizContent.put("out_trade_no", outTradeNo);
		bizContent.put("total_amount", totalAmount);
		bizContent.put("subject", subject);
		bizContent.put("product_code", PRODUCT_CODE);

		request.setBizContent(bizContent.toString());

		log.info("aliPay-调用支付页面接口-开始,请求参数:{}", JSON.toJSONString(request));

		AlipayTradePagePayResponse response = null;
		try {
			response = alipayClient.pageExecute(request);

			log.info("aliPay-调用支付页面接口-结束,请求参数:{}, 返回结果:{}", JSON.toJSONString(request),
					JSON.toJSONString(response));
		} catch (Exception e) {
			log.error(String.format("aliPay-调用支付页面接口-失败,请求参数:%s", JSON.toJSONString(request)), e);
		}
		// 是否调用成功
		boolean isSuccess = response != null && AliPayPcWebRespCodeEnums.SUCCESS.getCode().equals(response.getCode());

		Map<String, Object> resultMap = new HashMap<>();
		resultMap.put("isSuccess", isSuccess);

		if (isSuccess) {
			resultMap.put("body", response.getBody());
			resultMap.put("subMsg", "支付成功");
		} else {
			resultMap.put("subMsg", response == null ? "支付失败" : response.getSubMsg());
		}
		return resultMap;
	}

	/**
	 * 交易订单查询
	 * 
	 * @param out_trade_no
	 * @return
	 */
	public Map<String, Object> tradeQueryForPCWeb(String out_trade_no) {
		AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
		JSONObject bizContent = new JSONObject();
		bizContent.put("trade_no", out_trade_no);
		request.setBizContent(bizContent.toString());
		AlipayTradeQueryResponse response = null;
		try {
			response = alipayClient.execute(request);
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		Map<String, Object> resultMap = new HashMap<>();
		resultMap.put("isSuccess", response.isSuccess());
		if (response.isSuccess()) {
			System.out.println("调用成功");
			System.out.println(JSON.toJSONString(response));
			resultMap.put("status", response.getTradeStatus());
		} else {
			System.out.println("调用失败");
			System.out.println(response.getSubMsg());
			resultMap.put("subMsg", response.getSubMsg());
		}
		return resultMap;
	}

	/**
	 * 验证签名是否正确
	 * 
	 * @param sign
	 * @param content
	 * @return
	 */
	public boolean CheckSignIn(String sign, String content) {
		try {
			return AlipaySignature.rsaCheck(content, sign, alipayConfig.getPublickey(), CHART_TYPE, SIGN_TYPE);
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 将异步通知的参数转化为Map
	 * 
	 * @return
	 */
	public Map<String, String> paramstoMap(HttpServletRequest request) throws UnsupportedEncodingException {
		Map<String, String> params = new HashMap<String, String>();
		Map<String, String[]> requestParams = request.getParameterMap();
		for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}
			// 乱码解决，这段代码在出现乱码时使用。
//            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
			params.put(name, valueStr);
		}
		return params;
	}

}
